package org.nox.helloseries.core.connector.tracker;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.nox.helloseries.core.exceptions.TrackerSearchException;
import org.nox.helloseries.domain.NomTracker;
import org.nox.helloseries.domain.Serie;
import org.nox.helloseries.domain.SerieFileInformation;
import org.nox.helloseries.util.SeriePrettyPrinter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class AbstractRSSTorrentSearch
{

    protected static final Logger LOG = LoggerFactory.getLogger( AbstractRSSTorrentSearch.class );

    public AbstractRSSTorrentSearch()
    {
        super();
    }

    /**
     * @param serie
     * @return La liste des séries proposées par le tracker
     * @throws TrackerSearchException
     */
    public List<Serie> executeSearch( Serie serie ) throws TrackerSearchException
    {
        List<Serie> retour = new ArrayList<>();

        // Création de la série courante pour le traitement
        Serie serieCible = serie.clone();

        LOG.info( "Recherche de " + serieCible.toString() );

        LOG.info( "Url de recherche calculée pour " + serieCible + " : " + getUrlRecherche( serieCible ) );
        try
        {
            URL url = new URL( getUrlRecherche( serieCible ) );
            Document document = createSAXBuilder().build( url );

            // Réupération des données parsées
            List<Element> items = document.getRootElement().getChild( "channel" ).getChildren( "item" );

            // Pour chaque élement
            for ( Element e : items )
            {
            	String nomSerieRSS =getTitre( e ) ;
                Serie serieResultatCourant = new Serie(nomSerieRSS );
                // Traitement de la série que si son parsing est effectif
                if (StringUtils.isNotEmpty( serieResultatCourant.getNom())) {
                	// Maj des infos
                	SerieFileInformation serieFileInformation = serieResultatCourant.getSerieFileInformation();
                	serieFileInformation.setUrl( getUrl( e ) );
                	serieFileInformation.setSeeds( getSeeds( e ) );
                	serieFileInformation.setTailleFichier( getTailleFichier( e ) );
                	serieFileInformation.setNomTrackerSource( getNomTracker() );
                	retour.add( serieResultatCourant );
                }
                else {
                	LOG.warn("Série {} ignorée car non comprise",nomSerieRSS);
                }
            }
        }
        catch ( IOException e )
        {
            LOG.warn( e.getMessage() );
        }
        catch ( JDOMException e )
        {
            throw new TrackerSearchException( e.getMessage() );
        }

        LOG.info( retour.size() + " séries présentes dans le RSS " + getNomTracker() );
        LOG.debug( "Séries présentes dans le RSS " + SeriePrettyPrinter.rssPrettyPrint( retour ) );
        return retour;
    }

    private SAXBuilder createSAXBuilder()
    {
        SAXBuilder sxb = new SAXBuilder();
        sxb.setFeature( "http://xml.org/sax/features/validation", false );
        sxb.setFeature( "http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false );
        sxb.setFeature( "http://apache.org/xml/features/nonvalidating/load-external-dtd", false );
        return sxb;
    }

    protected abstract double getTailleFichier( Element e );

    protected abstract int getSeeds( Element e );

    // Accesseurs sur propriétés globales
    protected abstract String getUrlRecherche( Serie serie );

    protected abstract String getUrl( Element e );

    protected abstract String getTitre( Element e );

    protected abstract NomTracker getNomTracker();
}
